package com.aizuda.boot.modules.business.feishu;

import com.aizuda.boot.config.properties.FeiShuConfigProperties;
import com.aizuda.boot.modules.auth.domain.entity.ThirdUser;
import com.aizuda.boot.modules.auth.domain.entity.ThirdUserAuth;
import com.aizuda.boot.modules.auth.service.ThirdUserAuthService;
import com.aizuda.boot.modules.auth.service.ThirdUserService;
import com.aizuda.boot.modules.business.contract.entity.ContractEntity;
import com.aizuda.boot.modules.business.contract.service.ContractService;
import com.aizuda.boot.modules.system.entity.SysMessage;
import com.aizuda.boot.modules.system.entity.SysMessageReceiver;
import com.aizuda.boot.modules.system.mapper.SysMessageMapper;
import com.aizuda.boot.modules.system.service.ISysMessageReceiverService;
import com.aizuda.boot.modules.business.feishu.domain.AtUsersDTO;
import com.aizuda.boot.modules.business.feishu.domain.BotValues;
import com.aizuda.boot.modules.business.feishu.strategy.FeishuConfigStrategy;
import com.aizuda.bpm.engine.FlowLongEngine;
import com.aizuda.bpm.engine.entity.FlwHisInstance;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.gson.JsonParser;
import com.lark.oapi.Client;
import com.lark.oapi.core.utils.Jsons;
import com.lark.oapi.service.im.v1.model.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Author sangyirong
 * @ClassName FeishuBot
 * @Version 1.0
 * @Date 2025/7/11 19:06
 */

@Slf4j
@Component
public class FeishuBot {

    @Value("${feishu.default-redirect-uri}")
    private String defaultRedirectUri;

    @Resource
    private FeishuConfigStrategy feishuConfigStrategy;

    @Resource
    private SysMessageMapper sysMessageMapper;

    @Resource
    private ISysMessageReceiverService sysMessageReceiverService;

    @Resource
    private ThirdUserService thirdUserService;

    @Resource
    private ThirdUserAuthService thirdUserAuthService;

    @Resource
    private FlowLongEngine flowLongEngine;

    @Resource
    private ContractService contractService;

    public void sendBot(BotValues value) throws Exception {
        FeiShuConfigProperties.FeiShuAppConfig config = feishuConfigStrategy.getConfigByTenantKey(value.getTenantKey());
        if (null == config) {
            return;
        }
        FeiShuConfigProperties.FeiShuTemplateConfig template = feishuConfigStrategy.getTemplateConfig(config, value.getBusinessType());
        if (null == template) {
            return;
        }
        // 构建client
        Client client = Client.newBuilder(config.getAppId(), config.getAppSecret()).build();

        String content = getContent(template, value.getDynamicParams());

        // 创建请求对象
        CreateMessageReq req = CreateMessageReq.newBuilder()
                .receiveIdType("open_id")
                .createMessageReqBody(CreateMessageReqBody.newBuilder()
                        .receiveId(value.getOpenId())
                        .msgType("interactive")
                        .content(content)
                        .uuid(UUID.randomUUID().toString())
                        .build())
                .build();

        // 发起请求
        CreateMessageResp resp = client.im().v1().message().create(req);

        // 处理服务端错误
        if (!resp.success()) {
            System.out.println(String.format("code:%s,msg:%s,reqId:%s, resp:%s",
                    resp.getCode(), resp.getMsg(), resp.getRequestId(), Jsons.createGSON(true, false).toJson(JsonParser.parseString(new String(resp.getRawResponse().getBody(), StandardCharsets.UTF_8)))));
            throw new Exception("发送飞书机器人消息失败");
        }

        // 业务数据处理
        System.out.println(Jsons.DEFAULT.toJson(resp.getData()));
    }

    public String getContent(FeiShuConfigProperties.FeiShuTemplateConfig template, Map<String, Object> dynamicParams) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("type", "template");
        map.put("data", getTemplate(template, dynamicParams));
        return JSON.toJSONString(map);
    }

    public HashMap<String, Object> getTemplate(FeiShuConfigProperties.FeiShuTemplateConfig template, Map<String, Object> dynamicParams) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("template_id", template.getTemplateId());
        map.put("template_version", template.getTemplateVersionName());
        map.put("template_variable", dynamicParams);
        return map;
    }

    /**
     * 获取当前时间字符串
     */
    protected String getCurrentTime() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    public void sendMessage(Long messageId) {
        SysMessage message = sysMessageMapper.selectById(messageId);
        if (message == null) {
            return;
        }
        List<Long> userIds = sysMessageReceiverService.list(Wrappers.<SysMessageReceiver>lambdaQuery()
                        .eq(SysMessageReceiver::getMessageId, messageId)
                        .select(SysMessageReceiver::getUserId))
                .stream().map(SysMessageReceiver::getUserId).collect(Collectors.toList());

        List<Long> thirdUserIds = thirdUserAuthService.list(Wrappers.<ThirdUserAuth>lambdaQuery()
                        .in(ThirdUserAuth::getUserId, userIds)
                        .select(ThirdUserAuth::getThirdUserId))
                .stream().map(ThirdUserAuth::getThirdUserId).collect(Collectors.toList());
        List<ThirdUser> list = thirdUserService.list(Wrappers.<ThirdUser>lambdaQuery()
                .in(ThirdUser::getId, thirdUserIds));
        Map<String, List<ThirdUser>> thirdMap = list.stream().collect(Collectors.groupingBy(ThirdUser::getTenantKey));

        thirdMap.forEach((tenantKey, thirdUsers) -> {
            FeiShuConfigProperties.FeiShuAppConfig config = feishuConfigStrategy.getConfigByTenantKey(tenantKey);
            if (null == config) {
                return;
            }
            FeiShuConfigProperties.FeiShuTemplateConfig templateConfig = feishuConfigStrategy.getTemplateConfig(config, message.getBusinessType());
            if (null == templateConfig) {
                return;
            }

            thirdUsers.forEach(thirdUser -> {
                try {
                    List<String> templateParams = templateConfig.getTemplateParams();

                    HashMap<String, Object> map = new HashMap<>();
                    if (!CollectionUtils.isEmpty(templateParams)) {
                        templateParams.forEach(paramName -> {
                            map.put(paramName, getParaValue(paramName, message, config.getAppId()));
                        });
                    }

                    // 使用策略构建模版参数
                    BotValues botValues = feishuConfigStrategy.buildBotValues(map, thirdUser, templateConfig);
                    if (null == botValues) {
                        return;
                    }
                    // 发送消息
                    sendBot(botValues);
                    log.info("发送飞书机器人消息成功，tenantKey: {}, businessType: {}, thirdUserOpenId: {}",
                            thirdUser.getTenantKey(), message.getBusinessType(), thirdUser.getOpenId());
                } catch (Exception e) {
                    log.error("发送飞书机器人消息失败，tenantKey: {}, businessType: {},thirdUserOpenId: {} error: {}",
                            thirdUser.getTenantKey(), message.getBusinessType(), thirdUser.getOpenId(), e.getMessage());
                }
            });
        });

    }


    /**
     * at用户发送消息
     *
     * @param atUsersDTO
     * @return
     */
    public Boolean atUsers(AtUsersDTO atUsersDTO) {
        if (CollectionUtils.isEmpty(atUsersDTO.getUserIds())) {
            return false;
        }
        List<Long> thirdIds = thirdUserAuthService.lambdaQuery()
                .in(ThirdUserAuth::getUserId, atUsersDTO.getUserIds())
                .select(ThirdUserAuth::getThirdUserId)
                .list()
                .stream().map(ThirdUserAuth::getThirdUserId).collect(Collectors.toList());

        List<ThirdUser> thirdUserList = thirdUserService.lambdaQuery()
                .in(ThirdUser::getId, thirdIds)
                .list();
        if (CollectionUtils.isEmpty(thirdUserList)) {
            return false;
        }
        Map<String, List<ThirdUser>> thirdMap = thirdUserList.stream().collect(Collectors.groupingBy(ThirdUser::getTenantKey));
        thirdMap.forEach((tenantKey, thirdUsers) -> {
            FeiShuConfigProperties.FeiShuAppConfig config = feishuConfigStrategy.getConfigByTenantKey(tenantKey);
            if (null == config) {
                return;
            }
            FeiShuConfigProperties.FeiShuTemplateConfig templateConfig = feishuConfigStrategy.getTemplateConfig(config, atUsersDTO.getBusinessType());
            if (null == templateConfig) {
                return;
            }
            thirdUsers.forEach(thirdUser -> {
                try {
                    List<String> templateParams = templateConfig.getTemplateParams();
                    HashMap<String, Object> map = new HashMap<>();
                    if (!CollectionUtils.isEmpty(templateParams)) {
                        templateParams.forEach(paramName -> {
                            map.put(paramName, getParaValue(paramName, atUsersDTO, config.getAppId()));
                        });
                    }

                    // 使用策略构建模版参数
                    BotValues botValues = feishuConfigStrategy.buildBotValues(map, thirdUser, templateConfig);

                    // 发送消息
                    sendBot(botValues);
                    log.info("发送飞书机器人消息成功，thirdUserOpenId:{} tenantKey: {}, businessType: {}",
                            thirdUser.getOpenId(), thirdUser.getTenantKey(), atUsersDTO.getBusinessType());
                } catch (Exception e) {
                    log.error("发送飞书机器人消息失败，thirdUserOpenId:{} tenantKey: {}, businessType: {}, error: {}",
                            thirdUser.getOpenId(), thirdUser.getTenantKey(), atUsersDTO.getBusinessType(), e.getMessage(), e);
                }
            });
        });
        return true;
    }

    private <T> Object getParaValue(String paramName, T t, String appId) {
        if ("alarm_time".equals(paramName)) {
            return getCurrentTime();
        }
        if ("type".equals(paramName)) {
            try {
                Field field = t.getClass().getDeclaredField("businessType");
                field.setAccessible(true);
                Object value = field.get(t);
                return value == null ? null : value.toString();
            } catch (Exception e) {
                log.warn("获取参数值失败，参数名: {}, 错误: {}", paramName, e.getMessage());
                return null;
            }
        }
        if ("href".equals(paramName)) {
            String base = "https://applink.feishu.cn/client/web_app/open?appId=";
            try {
                Field field = t.getClass().getDeclaredField("url");
                field.setAccessible(true);
                Object value = field.get(t);
                return Map.of("url", base + appId + "&lk_target_url=" + URLEncoder.encode((value == null ? defaultRedirectUri : value.toString()), StandardCharsets.UTF_8));
            } catch (Exception e) {
                try {
                    Field businessType = t.getClass().getDeclaredField("businessType");
                    businessType.setAccessible(true);
                    String businessTypeValue = (String) businessType.get(t);
                    Field businessId = t.getClass().getDeclaredField("businessId");
                    businessId.setAccessible(true);
                    Long businessIdValue = (Long) businessId.get(t);
                    return Map.of("url", base + appId + "&lk_target_url=" + URLEncoder.encode(getRedirectUri(businessTypeValue, businessIdValue), StandardCharsets.UTF_8));

                } catch (Exception ex) {
                    log.warn("获取参数值失败，参数名: {}, 错误: {}", paramName, ex.getMessage());

                }


            }
        }
        try {
            Field field = t.getClass().getDeclaredField(paramName);
            field.setAccessible(true);
            Object value = field.get(t);
            return value == null ? null : value.toString();
        } catch (Exception e) {
            log.warn("获取参数值失败，参数名: {}, 错误: {}", paramName, e.getMessage());
            return null;
        }
    }

    private String getRedirectUri(String businessTypeValue, Long businessIdValue) {
        switch (businessTypeValue) {
            case "flowTodoTask":
            case "filing":
            case "performance":
                FlwHisInstance histInstance = flowLongEngine.queryService().getHistInstance(businessIdValue);
                if (histInstance == null) {
                    return defaultRedirectUri;
                }
                long count = contractService.count(Wrappers.<ContractEntity>lambdaQuery()
                        .eq(ContractEntity::getApprovalInstanceId, histInstance.getId()));
                if (count > 0) {
                    return defaultRedirectUri + "/contract/all-contracts?id=" + histInstance.getBusinessKey();
                } else {
                    return defaultRedirectUri + "/contract/negotiation-detail?id=" + histInstance.getBusinessKey();
                }
            case "negotiation":
                return defaultRedirectUri + "/contract/negotiation-detail?id=" + businessIdValue;
            default:
                return defaultRedirectUri;
        }
    }

}
